package cn.lingyangwl.agile.log;

import cn.lingyangwl.agile.common.security.utils.*;
import cn.lingyangwl.agile.system.model.rqrs.log.*;
import cn.lingyangwl.framework.log.*;
import cn.lingyangwl.framework.log.annotation.*;
import cn.lingyangwl.framework.log.common.*;
import cn.lingyangwl.framework.log.event.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Optional;

/**
 * @author shenguangyang 异步监听日志事件
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AccessLogListener {
	@Resource
	private RabbitTemplate rabbitTemplate;

	@Order
	@EventListener(WebLogEvent.class)
	public void saveSysLog(WebLogEvent event) {
		WebLogInfo info = (WebLogInfo) event.getSource();
		if (Objects.isNull(info)) {
			return;
		}
		Boolean writeDb = Optional.ofNullable(info.getLogAnnot()).map(AccessLog::writeDb).orElse(false);
		// 目前所有错误日志都写入数据库, 可以根据实际业务进行调整
		if (!writeDb && info.getStatus() == BizStatus.OK) {
			return;
		}
		AccessLogSaveReq req = new AccessLogSaveReq();

		req.setSummary(info.getSummary());
		req.setTag(info.getTagName());
		req.setStatus(info.getStatus() == BizStatus.OK ? "0" : "1");
		req.setUserName(SecurityUtils.getUserName());
		req.setBusinessType(info.getBizType());
		req.setOperatorType(info.getOprType());
		req.setErrorMsg(info.getErrorMsg());
		req.setJsonResult(info.getRespData() == null ? null : info.getRespData().toString());
		req.setTraceId(info.getTraceId());
		req.setRequestIp(info.getIp());
		req.setRequestParam(info.getReqData() == null ? null : info.getReqData().toString());
		req.setRequestMethod(info.getHttpMethod());
		req.setMethod(info.getClassMethod());
		req.setRequestUrl(info.getUrl());
		req.setCostTime(info.getCostTime());
		req.setLocation("");
		rabbitTemplate.convertAndSend(AccessLogMQ.EXCHANGE, AccessLogMQ.KEY, AccessLogMQ.build(req).toMessage());
	}
}
